/*****************************************************************************
 *
 * Copyright (c), 2004-2020,ShangHai Neotune Information Technology Co., Ltd.
 *
 * Module Name : v3_acc.h
 *
 * Author :    sean
 *
 * Date :    2004-02-05
 *
 * Version :    1.00
 *
 * Description :    
 *
 * Other :    
 *
 * Data Structure List: <Main Data Structure>
 *
 * Modification History
 * ---------------------------------------------------------------------------
 *  1: Data :      2004-02-05
 *    Author :     sean
 *    Version :    V100R001M00
 *    Modification : creation
 *
*****************************************************************************/

#if (!defined(v3_acc_inc))
#define v3_acc_inc

#ifdef __cplusplus
extern"C" {
#endif

#if (!defined(asn1_inc))
#include <asn1.h>
#endif

#if (!defined(buffer_inc))
#include <buffer_snmp.h>
#endif

#if (!defined(smi_inc))
#include <smi.h>
#endif

#define ETC_ACCESS_VIEW_MAX   32
#define ETC_ACCESS_GROUP_MAX  32
#define ETC_ACCESS_ACCESS_MAX 32

#ifdef NEOSNET_STRUCT_ALIGN
#pragma align 1
#endif

typedef struct SNMP_GROUP_S
        {
        struct SNMP_GROUP_S *next;
        sbits32_t  model;       /* security model, an index */
        bits8_t   *uname;       /* security name, other index */
        ALENGTH_T  uname_len;   /* length of security name */
        EBUFFER_T  grp_name;    /* group name */
        bits16_t   status;
        bits16_t   storage;
        } SNMP_GROUP_T;

/* global root pointer for group list */
extern SNMP_GROUP_T *root_group;

#define SNMP_Group_Set_Defaults(G) (MEMSET((G), 0, sizeof(SNMP_GROUP_T)), \
                                    EBufferInitialize(&((G)->grp_name)),  \
                                    (G)->storage = ETC_STO_NONVOL,        \
                                    (G)->status  = ETC_RS_NREADY)

extern SNMP_GROUP_T * SNMP_Group_Create     __((void));
extern void           SNMP_Group_Destroy    __((SNMP_GROUP_T *));
extern int            SNMP_Group_Install    __((SNMP_GROUP_T *, sbits32_t,
                                                bits8_t *, ALENGTH_T));
extern void           SNMP_Group_Deinstall  __((SNMP_GROUP_T *));
extern SNMP_GROUP_T * SNMP_Group_Lookup     __((sbits32_t, bits8_t *,
                                                ALENGTH_T));
extern SNMP_GROUP_T * SNMP_Group_Next       __((int, OIDC_T *));
extern SNMP_GROUP_T * SNMP_Group_Next_Group __((SNMP_GROUP_T *));
extern void           SNMP_Group_Name       __((SNMP_GROUP_T *, sbits32_t *, 
                                                bits8_t *, ALENGTH_T *));

#define SNMP_Group_Set_Group(G, S, L, F) \
        (EBufferAllocateLoad((F), &((G)->grp_name), (S), (L)))

#define SNMP_Group_Compare_Names(G1, G2) ((G1 == G2) ? 0 : 1)

#define SNMP_Group_Get_Group(G)           (EBufferStart(&((G)->grp_name)))
#define SNMP_Group_Get_Group_Len(G)       (EBufferUsed(&((G)->grp_name)))

#define SNMP_Group_Get_Status(G)          ((G)->status)
#define SNMP_Group_Set_Status(G, V)       ((G)->status = (bits16_t)(V))
#define SNMP_Group_Get_Storage(G)         ((G)->storage)
#define SNMP_Group_Set_Storage(G, V)      ((G)->storage = (bits16_t)(V))

typedef struct SNMP_ACC_GRP_S
        {
        struct SNMP_ACC_GRP_S *next;
        bits8_t   *grp_name;    /* group name, an index */ 
        ALENGTH_T  grp_len;
        struct SNMP_ACCESS_S *access;
        } SNMP_ACC_GRP_T;

typedef struct SNMP_ACCESS_S
        {
        struct SNMP_ACC_GRP_S *group;
        struct SNMP_ACCESS_S  *next;
        bits8_t   *prefix;      /* context prefix, an index */
        ALENGTH_T  prefix_len;
        int       prefix_match; /* prefix match, exact - 1, prefix - 2 */ 
        sbits32_t model;        /* security model, an index */
        sbits16_t level;        /* security level, an index */ 
        EBUFFER_T readview;     /* name of view for reading */
        EBUFFER_T writeview;    /* name of view for writing */
        EBUFFER_T notifyview;   /* name of view for notifies */
        int       status;
        int       storage;
        } SNMP_ACCESS_T;

#ifdef NEOSNET_STRUCT_ALIGN
#pragma align 0
#endif

#define ETC_ACCESS_EXACT  1
#define ETC_ACCESS_PREFIX 2

/* global root pointer for access list */
extern SNMP_ACC_GRP_T *root_access;

#define SNMP_V3_Access_Set_Defaults(A) (MEMSET((A), 0, sizeof(SNMP_ACCESS_T)),\
                                        (A)->prefix_match = ETC_ACCESS_EXACT, \
                                        EBufferInitialize(&((A)->readview)),  \
                                        EBufferInitialize(&((A)->writeview)), \
                                        EBufferInitialize(&((A)->notifyview)),\
                                        (A)->storage = ETC_STO_NONVOL,        \
                                        (A)->status  = ETC_RS_NIS)

extern SNMP_ACCESS_T * SNMP_V3_Access_Create    __((void));
extern void            SNMP_V3_Access_Destroy   __((SNMP_ACCESS_T *));
extern int             SNMP_V3_Access_Install   __((SNMP_ACCESS_T *,
                                                    bits8_t *, ALENGTH_T,
                                                    bits8_t *, ALENGTH_T,
                                                    sbits32_t, sbits32_t));
extern void            SNMP_V3_Access_Deinstall __((SNMP_ACCESS_T *));
extern SNMP_ACCESS_T * SNMP_V3_Access_Lookup    __((bits8_t *, ALENGTH_T,
                                                    bits8_t *, ALENGTH_T,
                                                    sbits32_t, sbits32_t));
extern SNMP_ACCESS_T * SNMP_V3_Access_Next      __((int, OIDC_T *)); 
extern SNMP_ACCESS_T * SNMP_V3_Access_Next_Access __((SNMP_ACCESS_T *));

extern void             SNMP_V3_Access_Name     __((SNMP_ACCESS_T *,
                                                    bits8_t   *, ALENGTH_T *,
                                                    bits8_t   *, ALENGTH_T *,
                                                    sbits32_t *, sbits32_t *));

extern SNMP_ACCESS_T * SNMP_V3_Access_Find      __((bits8_t *, ALENGTH_T,
                                                    bits8_t *, ALENGTH_T,
                                                    sbits32_t, sbits32_t));
extern int             SNMP_V3_Access_Set_View  __((SNMP_ACCESS_T *,
                                                    EBUFFER_T *, bits8_t *,
                                                    ALENGTH_T, unsigned int));

#define SNMP_V3_Access_Compare_Names(A1, A2)  ((A1 == A2) ? 0 : 1)

#define SNMP_V3_Access_Get_Read(A)        EBufferStart(&((A)->readview))
#define SNMP_V3_Access_Get_Read_Len(A)    EBufferUsed(&((A)->readview))
#define SNMP_V3_Access_Set_Read(A,S,L,F) \
                SNMP_V3_Access_Set_View(A, &((A)->readview), S, L, F)
#define SNMP_V3_Access_Get_Write(A)       EBufferStart(&((A)->writeview))
#define SNMP_V3_Access_Get_Write_Len(A)   EBufferUsed(&((A)->writeview))
#define SNMP_V3_Access_Set_Write(A,S,L,F) \
                SNMP_V3_Access_Set_View(A, &((A)->writeview), S, L, F)
#define SNMP_V3_Access_Get_Notify(A)      EBufferStart(&((A)->notifyview))
#define SNMP_V3_Access_Get_Notify_Len(A)  EBufferUsed(&((A)->notifyview))
#define SNMP_V3_Access_Set_Notify(A,S,L,F) \
                SNMP_V3_Access_Set_View(A, &((A)->notifyview), S, L, F)


#define SNMP_V3_Access_Get_Prefix_Match(A)    ((A)->prefix_match)
#define SNMP_V3_Access_Set_Prefix_Match(A, B) (((A)->prefix_match) = (B))

#define SNMP_V3_Access_Get_Status(A)      ((A)->status)
#define SNMP_V3_Access_Set_Status(A, V)   ((A)->status = (bits16_t)(V))
#define SNMP_V3_Access_Get_Storage(A)     ((A)->storage)
#define SNMP_V3_Access_Set_Storage(A, V)  ((A)->storage = (bits16_t)(V))

extern void grouptable_get   __((OIDC_T, int, OIDC_T *,
                                 SNMP_PKT_T *, VB_T *));

extern void grouptable_next   __((OIDC_T, int, OIDC_T *,
                                  SNMP_PKT_T *, VB_T *));

extern void grouptable_test   __((OIDC_T, int, OIDC_T *,
                                  SNMP_PKT_T *, VB_T *));

extern void grouptable_set   __((OIDC_T, int, OIDC_T *,
                                 SNMP_PKT_T *, VB_T *));

extern void accesstable_get   __((OIDC_T, int, OIDC_T *,
                                  SNMP_PKT_T *, VB_T *));

extern void accesstable_next   __((OIDC_T, int, OIDC_T *,
                                   SNMP_PKT_T *, VB_T *));

extern void accesstable_test   __((OIDC_T, int, OIDC_T *,
                                   SNMP_PKT_T *, VB_T *));

extern void accesstable_set   __((OIDC_T, int, OIDC_T *,
                                  SNMP_PKT_T *, VB_T *));

#ifdef __cplusplus
}
#endif

#endif /* #if (!defined(v3_acc_inc))*/
